﻿using CefGlue.Avalonia.Handlers;
using System;
using Xilium.CefGlue;

namespace CefGlue.Avalonia
{
    public class AvaloniaCefRenderProcessHandler : CefRenderProcessHandler
    {
        private CefDictionaryValue _extraInfo;

        protected override void OnBrowserCreated(CefBrowser browser, CefDictionaryValue extraInfo)
        {
            this._extraInfo = extraInfo != null ? extraInfo.Copy(true) : CefDictionaryValue.Create();
            base.OnBrowserCreated(browser, extraInfo);
        }

        protected override void OnContextCreated(CefBrowser browser, CefFrame frame, CefV8Context context)
        {
            if (_extraInfo != null)
            {
                foreach (var key in _extraInfo.GetKeys())
                {
                    CefDictionaryValue jsobject = (CefDictionaryValue)_extraInfo.GetDictionary(key);
                    CefV8Handler handler = new JavascriptCefV8Handler();
                    RegisterJavascriptFunction(jsobject, browser, context, handler);
                }
            }
        }

        private void RegisterJavascriptFunction(CefDictionaryValue jsobj, CefBrowser browser, CefV8Context context, CefV8Handler v8Handler)
        {
            var windowObj = context.GetGlobal();
            CefV8Value v8jsobject = CefV8Value.CreateObject();
            int objid = jsobj.GetInt("Id");
            string name = jsobj.GetString("Name");
            string typeName = jsobj.GetString("ObjectTypeName");
            string assemblyName = jsobj.GetString("AssemblyName");
            CefListValue methods = (CefListValue)jsobj.GetList("Methods");
            v8jsobject.SetValue("Id", CefV8Value.CreateInt(objid));
            v8jsobject.SetValue("Name", CefV8Value.CreateString(name));
            v8jsobject.SetValue("ObjectTypeName", CefV8Value.CreateString(typeName));
            v8jsobject.SetValue("AssemblyName", CefV8Value.CreateString(assemblyName));
            for (int i = 0; i < methods.Count; i++)
            {
                string functionName = methods.GetString(i);
                var jsfunc = CefV8Value.CreateFunction(functionName, v8Handler);
                v8jsobject.SetValue(functionName, jsfunc);
            }
            windowObj.SetValue(name, v8jsobject);
        }

        protected override void OnContextReleased(CefBrowser browser, CefFrame frame, CefV8Context context)
        {
            base.OnContextReleased(browser, frame, context);
        }
        protected override bool OnProcessMessageReceived(CefBrowser browser, CefFrame frame, CefProcessId sourceProcess, CefProcessMessage message)
        {
            //if (message.Name == "executeJs")
            //{
            //    var context = browser.GetMainFrame().V8Context;

            //    context.TryEval(message.Arguments.GetString(0), message.Arguments.GetString(1), 1, out CefV8Value value, out CefV8Exception exception);

            //    var response = CefProcessMessage.Create("executeJsResult");

            //    if (value.IsString)
            //    {
            //        response.Arguments.SetString(0, value.GetStringValue());
            //    }
            //    frame.SendProcessMessage(CefProcessId.Browser, response);
            //    return true;
            //}

            return true;
        }
        //protected override bool OnProcessMessageReceived(CefBrowser browser, CefProcessId sourceProcess, CefProcessMessage message)
        //{

        //}

        public event EventHandler WebKitInitialized;

        protected override void OnWebKitInitialized()
        {
            WebKitInitialized?.Invoke(this, EventArgs.Empty);
            base.OnWebKitInitialized();
        }
    }
}
